/**
 * 
 */
package com.manthano.util.context.profile;

import java.util.Date;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;

import com.google.gson.GsonBuilder;

/**
 * @author DELL
 */
public class MethodTraceProfiler implements MethodInterceptor
{
	Logger	logger	= Logger.getLogger(this.getClass());

	public Object invoke(MethodInvocation methodInvocation) throws Throwable
	{
		Object object = null;
		Long startTime = null;
		Long stopTime = null;
		MethodStats methodStats = new MethodStats();
		try
		{
			methodStats.setMethodName(methodInvocation.getMethod().getName());
			methodStats.setMethodParameters(methodInvocation.getArguments());
			startTime = System.currentTimeMillis();
			methodStats.setStartTime(new Date(startTime));
			object = methodInvocation.proceed();
			stopTime = System.currentTimeMillis() - startTime;
			methodStats.setStopTime(new Date(stopTime));
		}
		catch (Throwable e)
		{
			methodStats.setStopTime(new Date(System.currentTimeMillis() - startTime));
			logger.error(new GsonBuilder().setPrettyPrinting().create().toJson(methodStats), e);
		}
		return object;
	}

	@SuppressWarnings("unused")
	private static class MethodStats
	{
		private String		methodName			= null;
		private Object[]	methodParameters	= null;
		private Date		startTime			= null;
		private Date		stopTime			= null;

		/**
		 * @return the methodName
		 */
		public String getMethodName()
		{
			return methodName;
		}

		/**
		 * @param methodName
		 *            the methodName to set
		 */
		public void setMethodName(String methodName)
		{
			this.methodName = methodName;
		}

		/**
		 * @return the methodParameters
		 */
		public Object[] getMethodParameters()
		{
			return methodParameters;
		}

		/**
		 * @param methodParameters
		 *            the methodParameters to set
		 */
		public void setMethodParameters(Object[] methodParameters)
		{
			this.methodParameters = methodParameters;
		}

		/**
		 * @return the startTime
		 */
		public Date getStartTime()
		{
			return startTime;
		}

		/**
		 * @param startTime
		 *            the startTime to set
		 */
		public void setStartTime(Date startTime)
		{
			this.startTime = startTime;
		}

		/**
		 * @return the stopTime
		 */
		public Date getStopTime()
		{
			return stopTime;
		}

		/**
		 * @param stopTime
		 *            the stopTime to set
		 */
		public void setStopTime(Date stopTime)
		{
			this.stopTime = stopTime;
		}

	}
}
